
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "alloc.h"
#include "input.h"
#include "lex.h"
#include "str.h"
#include "expr.h"
#include "log.h"
#include "output.h"

static void compile(const char *sourcePath, const char *outPath)
{
    char *path, *name, *tmp;
    path = (char*) malloc(strlen(sourcePath) + 1);
    if (path == NULL) {
        LOGE("Memory exhausted");
        exit(EXT_MemoryFull);
    }
    strcpy(path, sourcePath);
    name = strrchr(path, '\\');
    if (name == NULL) {
        name = strrchr(path, '/');
    } else {
        tmp = strrchr(name, '/');
        if (tmp != NULL) name = tmp;
    }
    if (name == NULL) {
        name = path;
    } else {
        *name = '\0';
        name++;
    }
    tmp = strrchr(name, '.');
    if (tmp != NULL && tmp != name) {
        *tmp = '\0';
    }

    if (outPath == NULL && path != name) {
        outPath = path;
    }

    InitHeap(MainHeap);
    InitString();

    LOGV("start compile %s", sourcePath);
    ReadSourceFile(sourcePath);
    NextToken();
    AstNode root = ParseSourceFile();
    LOGV("end parse and start output");
    PrintCode(root, outPath, name);
    LOGV("stop compile %s", sourcePath);

    FreeHeap(MainHeap);
}

int main(int argc, char *argv[])
{
    InitLexer();

    if (argc < 3) {
        printf("Usage: Stream [options] -i stmfile\n");
        printf("Options:\n");
        printf("  -o file      Place the output into 'file'\n");
        printf("  -t indent    Indent of output file\n");
        printf("  -e           Output the enumeration definition\n");
        exit(0);
    }

    const char *inFile = NULL;
    const char *outPath = NULL;
    int i;
    for (i = 1; i < argc; i++) {
        if (argv[i][0] == '-' && argv[i][2] == '\0') {
            switch(argv[i][1]) {
            case 'i':
                i++;
                inFile = argv[i];
                break;
            case 'o':
                i++;
                outPath = argv[i];
                break;
            case 't':
                i++;
                Indent = argv[i];
                break;
            case 'e':
                OutputEnumDefine = 1;
                break;
            }
        } else {
            LOGE("Unknown cmd arg : %s", argv[i]);
            exit(0);
        }
    }
    if (inFile == NULL) {
        LOGE("There is no input file.");
        exit(0);
    }

    compile(inFile, outPath);

    DestroyHeap(MainHeap);
    return 0;
}
